package Server

import (
	"fmt"
	"net"
	"runtime"
)

type Server struct {
	Network string
	Address string
	Listen net.Listener
	Clients map[string]*Tcpconnection

	OnError func(err string)
	OnStart func(server *Server)

	OnConnect func(server *Server,client *Tcpconnection)
}
func (this *Server) StartInfo() {
	fmt.Println("========================================================")
	fmt.Println("========listen success on ", this.Address)
	fmt.Println("========using protocol    ", this.Network)
	fmt.Println("========golang version    ", runtime.Version())
	fmt.Println("========================================================")
}

func (this *Server) CallEventFunc(eventname string, args ...interface{}){
	switch eventname {
	case "error":
		this.OnError(args[0].(string))
	case "start":
		this.OnStart(this)
	case "connect":
		this.OnConnect(this,args[0].(*Tcpconnection))

	}
}

func (this *Server) AddClient(client *Tcpconnection){
	//ip:port
	//多线程
	this.Clients[client.Conn.RemoteAddr().String()] = client
}

func (this *Server) EventLoop(){
	for{
		conn, err := this.Listen.Accept()
		if err != nil{
			this.CallEventFunc("error",err.Error())
			return
		}

		client, err := MakeClient(conn,this.Network)
		if err != nil{
			this.CallEventFunc("error",err.Error())
			return
		}
		this.AddClient(client)
		this.CallEventFunc("connect", client)
		go client.HandMessage()
	}
}
func (this *Server) Start(){
	listen, err := net.Listen(this.Network,this.Address)
	if err != nil{
		//this.OnError(err.Error())
		this.CallEventFunc("error", err.Error())
		return
	}
	this.Listen = listen
	defer this.Listen.Close()

	this.StartInfo()
	this.CallEventFunc("start")

	this.EventLoop()

}